
package com.hlkj.pay.controller.openapi.order;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import java.util.List;

import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.util.collection.CollectionUtils;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.pay.app.merchant.IAcctAccountAppService;
import com.hlkj.pay.app.openapi.IOpenApiAppService;
import com.hlkj.pay.app.order.IAcctOrderAppService;
import com.hlkj.pay.common.CommonResultCode;
import com.hlkj.pay.infrastructure.model.merchant.fund.MerchantFundAccountBindDO;
import com.hlkj.pay.service.merchant.IMerchantFundAccountService;
import com.hlkj.pay.vo.openapi.fund.req.OpenApiFundAccountBindReq;
import com.hlkj.pay.vo.openapi.fund.req.OpenApiFundAccountSubmitReq;
import com.hlkj.pay.vo.openapi.fund.req.OpenApiFundAccountUpdateReq;
import com.hlkj.pay.vo.openapi.fund.resp.OpenApiFundAccountBindListResp;
import com.hlkj.pay.vo.openapi.fund.resp.OpenApiFundAccountBindResp;
import com.hlkj.pay.vo.openapi.fund.resp.OpenApiFundAccountResp;
import com.hlkj.pay.vo.openapi.order.resp.AcctPayOrderApiResp;
import com.hlkj.pay.vo.openapi.order.resp.AcctRefundOrderApiResp;
import com.hlkj.pay.vo.order.OpenApiResult;
import com.hlkj.pay.vo.order.req.AcctOrderQueryParamReq;
import com.hlkj.pay.vo.order.req.AcctPayOrderParamReq;
import com.hlkj.pay.vo.order.req.AcctRefundOrderParamReq;
import com.hlkj.pay.vo.order.req.OrderCommonParamReq;
import com.hlkj.pay.vo.order.resp.acct.AcctPayOrderResp;

import cn.hutool.core.bean.BeanUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * @author HlpayTeam
 * @date 2024/10/09 11:25
 */
@Tag(name = "汇分账-分账订单")
@RestController
@RequestMapping("/openapi/acct")
@RequiredArgsConstructor
@Slf4j
public class OpenApiOrderFundController {

    private final IOpenApiAppService openApiAppService;

    private final IAcctOrderAppService acctOrderAppService;

    private final IAcctAccountAppService acctAccountAppService;

    private final IMerchantFundAccountService merchantFundAccountService;

    @Operation(summary = "请求分账")
    @PostMapping("/order/submit")
    OpenApiResult<AcctPayOrderApiResp> submitAcctOrder(@Validated @RequestBody OrderCommonParamReq orderCommonParamReq) {
        try {
            AcctPayOrderParamReq paramReqParams = JsonUtils.parseObject(orderCommonParamReq.getBizContent(), AcctPayOrderParamReq.class);
            CommonResult<AcctPayOrderApiResp> payOrderRespCommonResult = acctOrderAppService.submitAcctOrder(paramReqParams);
            return openApiAppService.sign(payOrderRespCommonResult);
        }
        catch (Exception e) {
            return OpenApiResult.error(CommonResultCode.PARAMETER_ERROR.getCode(), e.getMessage());
        }
    }

    @Operation(summary = "分账退款")
    @PostMapping("/order/refund/submit")
    OpenApiResult<AcctRefundOrderApiResp> refundAcctOrder(@Validated @RequestBody OrderCommonParamReq orderCommonParamReq) {
        try {
            AcctRefundOrderParamReq paramReqParams = JsonUtils.parseObject(orderCommonParamReq.getBizContent(), AcctRefundOrderParamReq.class);
            CommonResult<AcctRefundOrderApiResp> payOrderRespCommonResult = acctOrderAppService.refundAcctOrder(paramReqParams);
            return openApiAppService.sign(payOrderRespCommonResult);
        }
        catch (Exception e) {
            return OpenApiResult.error(CommonResultCode.PARAMETER_ERROR.getCode(), e.getMessage());
        }
    }

    @Operation(summary = "分账订单查询")
    @PostMapping("/order/query")
    OpenApiResult<AcctPayOrderApiResp> queryAcctOrder(@Validated @RequestBody OrderCommonParamReq orderCommonParamReq) {
        try {
            AcctOrderQueryParamReq paramReqParams = JsonUtils.parseObject(orderCommonParamReq.getBizContent(), AcctOrderQueryParamReq.class);
            CommonResult<AcctPayOrderResp> commonResult = acctOrderAppService.queryAcctOrder(paramReqParams);
            CommonResult<AcctPayOrderApiResp> payOrderRespCommonResult = CommonResult.success();
            if(commonResult.isSuccess()){
                AcctPayOrderResp resultData = commonResult.getData();
                AcctPayOrderApiResp acctPayOrderApiResp=new AcctPayOrderApiResp();
                acctPayOrderApiResp.setPayOrderNo(resultData.getPayOrderNo());
                acctPayOrderApiResp.setMchOrderNo(resultData.getMchOrderNo());
                acctPayOrderApiResp.setMchAcctOrderNo(resultData.getMchAcctOrderNo());
                acctPayOrderApiResp.setBatchNo(resultData.getBatchNo());
                acctPayOrderApiResp.setAcctInfos(JsonUtils.toJsonStringNotNull(resultData.getAcctInfos()));
                payOrderRespCommonResult.setData(acctPayOrderApiResp);
            }else {
                payOrderRespCommonResult=CommonResult.error(commonResult.getCode(),commonResult.getMsg());
            }
            return openApiAppService.sign(payOrderRespCommonResult);
        }
        catch (Exception e) {
            return OpenApiResult.error(CommonResultCode.PARAMETER_ERROR.getCode(), e.getMessage());
        }
    }

    @Operation(summary = "分账完结")
    @PostMapping("/order/finish")
    OpenApiResult<AcctPayOrderApiResp> finishAcctOrder(@Validated @RequestBody OrderCommonParamReq orderCommonParamReq) {
        try {
            AcctOrderQueryParamReq paramReqParams = JsonUtils.parseObject(orderCommonParamReq.getBizContent(), AcctOrderQueryParamReq.class);
            CommonResult<AcctPayOrderResp> commonResult = acctOrderAppService.finishAcctOrder(paramReqParams);
            CommonResult<AcctPayOrderApiResp> payOrderRespCommonResult = CommonResult.success();
            if(commonResult.isSuccess()){
                AcctPayOrderResp resultData = commonResult.getData();
                AcctPayOrderApiResp acctPayOrderApiResp=new AcctPayOrderApiResp();
                acctPayOrderApiResp.setPayOrderNo(resultData.getPayOrderNo());
                acctPayOrderApiResp.setMchOrderNo(resultData.getMchOrderNo());
                acctPayOrderApiResp.setMchAcctOrderNo(resultData.getMchAcctOrderNo());
                acctPayOrderApiResp.setBatchNo(resultData.getBatchNo());
                payOrderRespCommonResult.setData(acctPayOrderApiResp);
            }else {
                payOrderRespCommonResult = CommonResult.error(commonResult.getCode(),commonResult.getMsg());
            }
            return openApiAppService.sign(payOrderRespCommonResult);
        }
        catch (Exception e) {
            return OpenApiResult.error(CommonResultCode.PARAMETER_ERROR.getCode(), e.getMessage());
        }
    }

    @Operation(summary = "分账退款查询")
    @PostMapping("/order/refund/query")
    OpenApiResult<AcctRefundOrderApiResp> queryRefundAcctOrder(@Validated @RequestBody OrderCommonParamReq orderCommonParamReq) {
        try {
            AcctOrderQueryParamReq paramReqParams = JsonUtils.parseObject(orderCommonParamReq.getBizContent(), AcctOrderQueryParamReq.class);
            CommonResult<AcctRefundOrderApiResp> payOrderRespCommonResult = acctOrderAppService.queryRefundAcctOrder(paramReqParams);
            return openApiAppService.sign(payOrderRespCommonResult);
        }
        catch (Exception e) {
            return OpenApiResult.error(CommonResultCode.PARAMETER_ERROR.getCode(), e.getMessage());
        }
    }

    @Operation(summary = "分账接收方录入")
    @PostMapping("/account/submit")
    OpenApiResult<OpenApiFundAccountResp> submitAccount(@Validated @RequestBody OrderCommonParamReq orderCommonParamReq) {
        try {
            OpenApiFundAccountSubmitReq fundAccountReq = JsonUtils.parseObject(orderCommonParamReq.getBizContent(), OpenApiFundAccountSubmitReq.class);
            CommonResult<OpenApiFundAccountResp> payOrderRespCommonResult = acctAccountAppService.submitAccount(fundAccountReq);
            return openApiAppService.sign(payOrderRespCommonResult);
        }
        catch (Exception e) {
            e.printStackTrace();
            return OpenApiResult.error(CommonResultCode.PARAMETER_ERROR.getCode(), e.getMessage());
        }
    }

    @Operation(summary = "分账接收方更新")
    @PostMapping("/account/update")
    OpenApiResult<OpenApiFundAccountResp> updateAccountCard(@Validated @RequestBody OrderCommonParamReq orderCommonParamReq) {
        try {
            OpenApiFundAccountUpdateReq fundAccountReq = JsonUtils.parseObject(orderCommonParamReq.getBizContent(), OpenApiFundAccountUpdateReq.class);
            CommonResult<OpenApiFundAccountResp> payOrderRespCommonResult = acctAccountAppService.updateAccountCard(fundAccountReq);
            return openApiAppService.sign(payOrderRespCommonResult);
        }
        catch (Exception e) {
            e.printStackTrace();
            return OpenApiResult.error(CommonResultCode.PARAMETER_ERROR.getCode(), e.getMessage());
        }
    }

    @Operation(summary = "分账关系绑定")
    @PostMapping("/account/bind")
    OpenApiResult<Void> accountBind(@Validated @RequestBody OrderCommonParamReq orderCommonParamReq) {
        try {
            OpenApiFundAccountBindReq fundAccountBindReq = JsonUtils.parseObject(orderCommonParamReq.getBizContent(), OpenApiFundAccountBindReq.class);
            CommonResult<Void> payOrderRespCommonResult = acctAccountAppService.accountBind(fundAccountBindReq);
            return openApiAppService.sign(payOrderRespCommonResult);
        }
        catch (Exception e) {
            e.printStackTrace();
            return OpenApiResult.error(CommonResultCode.PARAMETER_ERROR.getCode(), e.getMessage());
        }
    }

    @Operation(summary = "分账关系解绑")
    @PostMapping("/account/unbind")
    OpenApiResult<Void> accountUnBind(@Validated @RequestBody OrderCommonParamReq orderCommonParamReq) {
        try {
            OpenApiFundAccountBindReq accountBindReq = JsonUtils.parseObject(orderCommonParamReq.getBizContent(), OpenApiFundAccountBindReq.class);
            CommonResult<Void> payOrderRespCommonResult = acctAccountAppService.accountUnBind(accountBindReq);
            return openApiAppService.sign(payOrderRespCommonResult);
        }
        catch (Exception e) {
            e.printStackTrace();
            return OpenApiResult.error(CommonResultCode.PARAMETER_ERROR.getCode(), e.getMessage());
        }
    }

    @Operation(summary = "分账关系查询")
    @PostMapping("/account/query")
    OpenApiResult<AcctPayOrderApiResp> accountQuery(@Validated @RequestBody OrderCommonParamReq orderCommonParamReq) {
        try {
            OpenApiFundAccountBindReq accountBindReq = JsonUtils.parseObject(orderCommonParamReq.getBizContent(), OpenApiFundAccountBindReq.class);
            OpenApiFundAccountBindResp openApiFundAccountBindResp = new OpenApiFundAccountBindResp();
            openApiFundAccountBindResp.setMchChannelCode(accountBindReq.getMchChannelCode());
            List<MerchantFundAccountBindDO> merchantFundAccountBinds = merchantFundAccountService.queryAccountBindList(accountBindReq.getMchChannelCode());

            acctAccountAppService.queryAccountBindList(accountBindReq.getMchChannelCode());
            if (CollectionUtils.isNotEmpty(merchantFundAccountBinds)) {
                openApiFundAccountBindResp.setAccountList(JsonUtils.toJsonStringNotNull(BeanUtil.copyToList(merchantFundAccountBinds, OpenApiFundAccountBindListResp.class)));
            }
            return openApiAppService.sign(CommonResult.success(openApiFundAccountBindResp));
        }
        catch (Exception e) {
            return OpenApiResult.error(CommonResultCode.PARAMETER_ERROR.getCode(), e.getMessage());
        }
    }

}
